package com.cnswhy.cloud.server.app.controller.customer;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cnswhy.cloud.common.core.exception.BizException;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.BeanPlusUtil;
import com.cnswhy.cloud.common.core.utils.CnswhyUtil;
import com.cnswhy.cloud.common.core.utils.Kits;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.app.controller.BaseController;
import com.cnswhy.cloud.server.common.entity.enumeration.BankCardType;
import com.cnswhy.cloud.server.core.base.BankService;
import com.cnswhy.cloud.server.core.channel.hcpay.dto.BankCardVerifyDto;
import com.cnswhy.cloud.server.core.channel.hcpay.service.HcpayService;
import com.cnswhy.cloud.server.core.constant.RedisConstant;
import com.cnswhy.cloud.server.core.dto.CustomerBankSaveDTO;
import com.cnswhy.cloud.server.core.entity.BaseBankBin;
import com.cnswhy.cloud.server.core.entity.Customer;
import com.cnswhy.cloud.server.core.entity.CustomerBank;
import com.cnswhy.cloud.server.core.oem.OemService;
import com.cnswhy.cloud.server.core.query.QueryGenerator;
import com.cnswhy.cloud.server.core.service.customer.CustomerBankService;
import com.cnswhy.cloud.server.core.service.customer.CustomerService;
import com.cnswhy.cloud.server.core.vo.RespVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping("/bank")
@Api(tags = "银行账号信息")
@Slf4j
public class CustomerBankController extends BaseController {

    @Autowired
    private CustomerBankService customerBankService;

    @Autowired
    private RedisService redisService;
    @Autowired
    private OemService oemService;
    @Autowired
    BankService bankService;
    @Autowired
    HcpayService hcpayService;
    @Autowired
    CustomerService customerService;

    @ApiOperation(value = "查询分页数据", httpMethod = "POST")
    @ApiParam(name = "bo", value = "查询Bo")
    @RequestMapping("/ajaxBankData")
    @ResponseBody
    public RespVo ajaxBankData(HttpServletRequest request,
                               @RequestParam(name = "currentPage", defaultValue = "1") Integer currentPage,
                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, CustomerBank bo) {
        log.info("查询银行卡信息：{} {} {}", JSON.toJSONString(bo), currentPage, currentPage);
        RespVo vo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer( request);
            bo.setCustomerId(loginCustomer.getId());
            QueryWrapper<CustomerBank> queryWrapper = QueryGenerator.initQueryWrapper(bo);
            queryWrapper.orderByDesc("create_time");
            Page<CustomerBank> page = new Page<>(currentPage, pageSize);
            IPage<CustomerBank> pageList = customerBankService.page(page, queryWrapper);
            vo.setCode(RespVo.CODE_SUCCESS);
            vo.setResult(pageList);
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("查询银行卡信息失败");
            log.error("查询银行卡信息失败", e);
        }
        return vo;
    }

    @ApiOperation(value = "保存银行信息", httpMethod = "POST")
    @ApiParam(name = "entity", value = "银行账号实体")
    @RequestMapping("/saveData")
    @ResponseBody
    public RespVo saveData(CustomerBankSaveDTO entity, HttpServletRequest request) {
        log.info("保存银行信息：{}", JSON.toJSONString(entity));

        RespVo vo = new RespVo();
        try {
            if (StringUtils.isBlank(entity.getBankNum())
                    || StringUtils.isBlank(entity.getMobile())) {
                vo.setCode(RespVo.CODE_ERROR);
                vo.setMessage("参数异常");
                return vo;
            }/**/

            if(!CnswhyUtil.checkBankCard(entity.getBankNum())){
                vo.setCode(RespVo.CODE_ERROR);
                vo.setMessage("卡号校验失败");
                return vo;
            }
            if (StringUtils.isBlank(entity.getSysCode())) {
                vo.setCode(RespVo.VALIDATE_ERROR);
                vo.setMessage("验证码为空");
                return vo;
            }

            if (!checkVerifyCode(entity.getMobile(), entity.getSysCode())) {
                vo.setCode(RespVo.VALIDATE_ERROR);
                vo.setMessage("验证码错误");
                return vo;
            }
            Customer loginCustomer = getLoginCustomer( request);
            loginCustomer = customerService.getById(loginCustomer.getId());
            entity.setIdCard(loginCustomer.getVerifyIdNo());
            entity.setAccountName(loginCustomer.getVerifyName());
            if (!("1".equals(loginCustomer.getVerifyStatus()))) {
                vo.setCode(RespVo.VALIDATE_ERROR);
                vo.setMessage("未实名不能添加卡号！");
                return vo;
            }
            /*if (!(entity.getIdCard().equals(loginCustomer.getVerifyIdNo()))) {
                log.error("身份证匹配失败:{} {}", entity.getIdCard(),loginCustomer.getVerifyIdNo());
                vo.setCode(RespVo.VALIDATE_ERROR);
                vo.setMessage("只能添加本人的卡号！");
                return vo;
            }*/
            hcpayService.bankCardVerify(BankCardVerifyDto.builder()
                    .cardId(entity.getBankNum())
                    .name(entity.getAccountName())
                    .idNo(entity.getIdCard())
                    .phone(entity.getMobile())
                    .orderId("verify" + Kits.Date.getyyyyMMddHHmmss() + Kits.Random.getRandom(1000, 10000)).build(), "882035716004024");
            entity.setCustomerId(loginCustomer.getId());
            CustomerBank customerBank = customerBankService.getOne(Wraps.<CustomerBank>lbQ().eq(CustomerBank::getBankNum,entity.getBankNum()).eq(CustomerBank::getCustomerId,loginCustomer.getId()));
            if(customerBank != null) {
                customerBank.setMobile(entity.getMobile());
                customerBank.setCvv(entity.getCvv());
                customerBank.setExpdate(entity.getExpdate());
                customerBankService.updateById(customerBank);
            }else if(customerBank == null){
                //customerBank = BeanPlusUtil.toBean(entity, CustomerBank.class);
                customerBank = new CustomerBank();
                customerBank.setCustomerId(entity.getCustomerId());
                customerBank.setBankNum(entity.getBankNum());
                customerBank.setMobile(entity.getMobile());
                customerBank.setIdCard(entity.getIdCard());
                customerBank.setAccountName(entity.getAccountName());
                customerBank.setCvv(entity.getCvv());
                customerBank.setExpdate(entity.getExpdate());
                try {
                    BaseBankBin baseBankBin = bankService.getBankBinByCardId(customerBank.getBankNum());
                    if("00".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.UNKNOWN.getVal());
                    }else if("01".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.DEBIT_CARD.getVal());
                    }else if("02".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.CREDIT_CARD.getVal());
                        if(StringUtils.isBlank(entity.getExpdate())){
                            throw new BizException("有效期不可为空");
                        }
                        if(entity.getExpdate().length() != 4) {
                            throw new BizException("有效期格式错误，正确格式为:MMYY(月份/年份)");
                        }
                        if(StringUtils.isBlank(entity.getCvv())){
                            throw new BizException("CVV不可为空");
                        }
                    } else if("03".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.SEMI_CREDIT_CARD.getVal());
                    }else if("04".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.DEBIT_CREDIT_CARD.getVal());
                    }else if("05".equals(baseBankBin.getCardType())){
                        customerBank.setCardType(BankCardType.PREPAID_CARD.getVal());
                    }
                    customerBank.setBankAbbr(baseBankBin.getBankAbbr());
                    customerBank.setBankName(baseBankBin.getBankName());
                } catch (BizException e) {
                    customerBank.setCardType(BankCardType.UNKNOWN.getVal());
                }
                List<CustomerBank> queryPage = customerBankService.getCustomerBankList(loginCustomer.getId());
                if(queryPage != null && queryPage.size() < 1 && (BankCardType.DEBIT_CARD.getVal() == customerBank.getCardType().intValue())){
                    customerBank.setIsDefault(1);
                }else{
                    customerBank.setIsDefault(0);
                }
                customerBankService.save(customerBank);
            }
            vo.setCode(RespVo.CODE_SUCCESS);
            vo.setMessage("保存成功");
        } catch (BizException e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage(e.getMessage());
            log.error("保存失败:", e.getMessage());
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("保存失败");
            log.error("保存失败", e);
        }
        return vo;
    }


    @ApiOperation(value = "删除银行信息", httpMethod = "POST")
    @ApiParam(name = "id", value = "银行账号id")
    @RequestMapping("/delete")
    @ResponseBody
    public RespVo delete(Long id) {
        RespVo vo = new RespVo();
        try {
            customerBankService.removeById(id);
            vo.setCode(RespVo.CODE_SUCCESS);
            vo.setMessage("");
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("删除失败");
            log.error("删除失败", e);
        }

        return vo;
    }
    @ApiOperation(value = "设置默认结算卡", httpMethod = "POST")
    @ApiParam(name = "id", value = "银行账号id")
    @RequestMapping("/setDefault")
    @ResponseBody
    @Transactional
    public RespVo setDefault(Long id, HttpServletRequest request) {
        RespVo vo = new RespVo();
        try {
            Customer loginCustomer = getLoginCustomer( request);
            CustomerBank customerBank = customerBankService.getById(id);
            if(customerBank.getCardType() != null && BankCardType.DEBIT_CARD.getVal() == customerBank.getCardType()){
                if(customerBank.getIsDefault().intValue() != 1){
                    List<CustomerBank> customerBanks = customerBankService.list(Wraps.<CustomerBank>lbQ().eq(CustomerBank::getIsDefault,1).eq(CustomerBank::getCustomerId,loginCustomer.getId()));
                    for(CustomerBank customerBank1 : customerBanks){
                        customerBank1.setIsDefault(0);
                        customerBankService.updateById(customerBank1);
                    }
                    customerBank.setIsDefault(1);
                    customerBankService.updateById(customerBank);
                    loginCustomer = customerService.getById(loginCustomer.getId());

                    loginCustomer.setVerifyPhone(customerBank.getMobile());
                    loginCustomer.setVerifyCard(customerBank.getBankNum());
                    customerService.updateById(loginCustomer);
                }

                vo.setCode(RespVo.CODE_SUCCESS);
                vo.setMessage("");
            }else{
                throw new BizException("请设置储蓄卡为结算卡");
            }

        } catch (BizException e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage(e.getMessage());
            log.error(e.getMessage());
        } catch (Exception e) {
            vo.setCode(RespVo.CODE_ERROR);
            vo.setMessage("修改默认结算卡失败");
            log.error("修改默认结算卡失败", e);
        }

        return vo;
    }

    public boolean checkVerifyCode(String mobile, String verifyCode) {
        if (org.apache.commons.lang.StringUtils.isBlank(mobile) || org.apache.commons.lang.StringUtils.isBlank(verifyCode)) {
            return false;
        }

        String redisVerifyCode = (String) redisService.get(RedisConstant.PASS_VERIFY_CODE_REDIS_KEY + mobile);
        if (org.apache.commons.lang.StringUtils.isBlank(redisVerifyCode) || !verifyCode.equals(redisVerifyCode)) {
            return false;
        }

        return true;
    }
}
